///@file Vector.h
///@brief Declaration of the class representing a Vector
///@author Arnaud Duval
///@version 0.0
///@date 2010/04/09


#ifndef VECTOR_H
#define VECTOR_H

#include <assert.h>
#include <iostream>


///@class Vector
///@brief Class defining a Vector
/// A vector is an array of value
class Vector
{
  protected:
    ///@brief Size of vector
    unsigned int size;
    ///@brief Array of components
    double *a;
  public:
    ///@brief Default constructor
    Vector();
    ///@brief Constructor precising the size of the vector
    Vector(unsigned int, double val = 0.);
    ///@brief Copy constructor
    Vector(const Vector &);
    ///@brief Copy constructor for temporary object
    Vector(Vector*);
    ///@brief Destructor
    ~Vector();
    ///@brief Overload of = operator
    Vector& operator=(const Vector &);	//Tested
    ///@brief Overload of = operator for temporary object
    Vector& operator=(Vector*);
    ///@brief Overload of &= operator : copy without size check
    ///@bug Not tested and hazardous
    Vector& operator&=(const Vector &);
    ///@brief Overload of [] operator
    double& operator[](unsigned int) const;
    ///@brief Overload of += operator
    void operator += (const Vector&);
    ///@brief Overload of -= operator
    void operator -= (const Vector&);
	///@brief Overload of /= operator
	void operator /= (const double&);
    ///@brief Compute euclidian norm of a vector
    double Euclide_Norm();	//Tested
    ///@brief Return dimension of vector
    unsigned int Dim() const;
    ///@brief Resizes the vector
    void resize(unsigned int);	//Tested
    ///@brief Swap 2 components
    void swap(unsigned int, unsigned int);	//Tested
    ///@brief Add a subvector into current vector
    void AddSubVector(Vector, unsigned int);
    ///@brief Fill vector with a Sobol sequence on [0,1]
    void FillSobol();	//Tested
    ///@brief Sort the vector values with bubble sort algorithm
    void BubbleSort();	//Tested
    ///@brief Generate permutations
    Vector GetNextPermutation(int*, bool reset = false);
    ///@brief Return maximum value of Vector terms
    double Max();
    ///@brief Return the sum of Vector terms
    double Sum();	//Tested
    ///@brief Return average value of Vector components
    double Average();
    ///@brief Set all components to zero
    void Nullify();

    ///@brief Overload of + operator
    friend Vector operator + (const Vector&, const Vector&);	//Tested
    ///@brief Overload of - operator
    friend Vector operator - (const Vector&, const Vector&);	//Tested
    ///@brief Overload of | operator : scalar product
    friend double operator | (const Vector&, const Vector&);
    ///@brief Overload of * operator : product vector-scalar
    friend Vector operator * (const Vector&, const double&);
    ///@brief Overload of * operator : product scalar-vector
    friend Vector operator * (const double&, const Vector&);
    ///@brief Overload of / operator : division of a vector by a scalar
    friend Vector operator / (const Vector& , const double&);
    ///@brief Happend a vector to another one
    friend Vector operator && (const Vector&, const Vector&);
    ///@brief Overload of << operator
    friend std::ostream& operator<<(std::ostream &, const Vector&);
    ///@brief Overload of >> operator
    friend std::istream& operator>>(std::istream &, const Vector&);
};


#endif
